package com.base.Filter.sign;

import com.base.po.voip.apiauthor;
import com.base.service.ApiauthorService;
import com.base.utils.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;

/**
 * 签名工具类
 */
@Slf4j
@Component
public class SignUtil {
    public static SignUtil signUtil;

    @PostConstruct
    public void init() {
        signUtil = this;
    }

    @Autowired
    ApiauthorService apiauthorService;


    /**
     * @param params 所有的请求参数都会在这里进行排序加密
     * @return 验证签名结果
     */
    public static boolean verifySign(SortedMap<Object, Object> params) {
        String urlSign = params.get("sign") != null ? params.get("sign").toString() : "";
        String urlappkey = params.get("appkey") != null ? params.get("appkey").toString() : "";
        String urltimestamp = params.get("timestamp") != null ? params.get("timestamp").toString() : "";
        apiauthor autor = signUtil.apiauthorService.getUserByApiAutor(urlappkey);
        if (autor == null) {
            return false;
        }
        String systemSecret = autor.getAppsecret();
        Long achtime = Long.parseLong(urltimestamp);
        //时间不能大于10分钟
        if ((System.currentTimeMillis() - achtime) / (1000 * 60) > 10) {
            return false;
        }
//        if (!urlappsecret.equals(systemSecret)){
//           return false;
//        }
        //必须是已经注册过的autor
        if (autor == null) {
            return false;
        }
//        log.info("Url Sign : {}", urlSign);
        //参数不能为空
        if (params == null || StringUtils.isEmpty(urlSign)) {
            return false;
        }
        Map<Object, Object> maps = params;
        String characterEncoding = "UTF-8";
        //getSign之前必须要去除Sign

        Iterator iterator = params.keySet().iterator();
        while (iterator.hasNext()) {
            String key = (String) iterator.next();
            if ("sign".equals(key)) {
                iterator.remove();
                params.remove(key);
            }
        }
        //把参数加密
        String paramsSign = getSign(characterEncoding, params, systemSecret);
        log.info("Param Sign : {}", paramsSign);
        return !StringUtils.isEmpty(paramsSign) && urlSign.equals(paramsSign);
    }

    /**
     * @param params 所有的请求参数都会在这里进行排序加密
     * @return 得到签名
     */
//    public static String getParamsSign(SortedMap<String, String> params,String key) {
//        //要先去掉 Url 里的 Sign
//        params.remove("sign");
//        String paramsJsonStr = JSONObject.toJSONString(params);
////        String appkey=
//        return DigestUtils.md5DigestAsHex(paramsJsonStr.getBytes()).toUpperCase();
//    }
    public static boolean verifyParamNessary(SortedMap<Object, Object> params) {
        if (null != params.get("appkey") && !params.get("appkey").equals("") &&
                null != params.get("timestamp") && !params.get("timestamp").equals("") &&
                null != params.get("sign") && !params.get("sign").equals("")) {
            return true;
        }
        return false;
    }

    public static String getSign(String characterEncoding, SortedMap<Object, Object> parameters, String key) {
        StringBuffer sb = new StringBuffer();
        StringBuffer sbkey = new StringBuffer();
        Set es = parameters.entrySet();  //所有参与传参的参数按照accsii排序（升序）
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            //去除sign参数
            Object v = entry.getValue();
            //空值不传递，不参与签名组串
            if (null != v && !"".equals(v)) {
                sb.append(k + "=" + v + "&");
                sbkey.append(k + "=" + v + "&");
            }
        }
        sbkey = sbkey.append("key=" + key);
        System.out.println("加密前的参数:" + sbkey);
        //MD5加密,结果转换为大写字符
        String sign = MD5Util.MD5Encode(sbkey.toString(), characterEncoding).toUpperCase();
        System.out.println("sign:" + sign);
        return sign;
    }
}